package trystero.lib.http.hc;

import java.net.URL;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Vector;
import java.util.List;
import java.util.Hashtable;
import java.util.Enumeration;

import org.apache.http.cookie.Cookie;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import trystero.lib.http.HTTPClient;
import trystero.lib.http.HTTPRequestState;
import trystero.lib.http.POSTData;
import trystero.lib.util.StreamUtils;

public class HTTPClientImpl extends HTTPClient
{
   DefaultHttpClient client;

   protected DefaultHttpClient client() { return this.client; }
   protected void client(DefaultHttpClient client) { this.client = client; }

   public InputStream get(HTTPRequestState state) throws Exception
   {
      if(client() == null)
         client(new DefaultHttpClient());

      if(state.cookie() != null)
	 client().getCookieStore().addCookie(adapt(state.cookie()));

      HttpGet get = new HttpGet(state.url());

      if(state.headers() != null)
      {
         Hashtable headers = state.headers();
         for(Enumeration e = headers.keys(); e.hasMoreElements(); )
	 {
	   Object key = e.nextElement();
           get.addHeader((String)key, (String)headers.get(key));
	 }
      }
	 
      HttpResponse response = client.execute(get);
      HttpEntity entity = response.getEntity();
      return new EntityInputStream(entity);
   }

   public InputStream post(HTTPRequestState state) throws Exception
   {
      if(client() == null)
         client(new DefaultHttpClient());

      if(state.cookie() != null)
	 client.getCookieStore().addCookie(adapt(state.cookie()));

      HttpPost post = new HttpPost(state.url());

      if(state.headers() != null)
      {
         Hashtable headers = state.headers();
         for(Enumeration e = headers.keys(); e.hasMoreElements(); )
	 {
	   Object key = e.nextElement();
           post.addHeader((String)key, (String)headers.get(key));
	 }
      }
	
      if(state.data() != null)
         post.setEntity(new UrlEncodedFormEntity(adapt(state.data())));

      HttpResponse response = client.execute(post);
      //System.out.println(">>>"+ ((StatusLine) response.getStatusLine()).getReasonPhrase());
      HttpEntity entity = response.getEntity();
      return new EntityInputStream(entity);
   }

   private static List<NameValuePair> adapt(POSTData data)
   {
      List<NameValuePair> list = new Vector<NameValuePair>();

      Vector keys = data.keys();
      Vector values = data.values();

      for(int i = 0; i < keys.size(); i++)
         list.add(new BasicNameValuePair((String)keys.get(i), (String)values.get(i)));

      return list;      
   }

   private static org.apache.http.cookie.Cookie adapt(trystero.lib.http.Cookie cookie)
   {
      BasicClientCookie ret = new BasicClientCookie(cookie.key(), cookie.value());
      ret.setDomain(cookie.domain());
      ret.setPath(cookie.path());
      // XXX cookie expiry

      return ret;
   }
}
